本篇擷取重點:
一、網頁跳轉的基礎比較總覽
比較項 | Response.Redirect() | Server.Transfer() | Server.Execute() |
---|---|---|---|
目的地 | 可以切換到任何的網頁 | 只能切換到同目錄或子目錄的網頁 | 同Transfer() |
安全性 | url會變成你所指向的新網頁 | url不變,隱藏了新網頁的url及附帶的參數值 | 同Transfer() |
傳遞容量 | 受各瀏覽器的網址欄位長度限制(含傳遞引數) | 無 | 同Transfer() |
連接伺服器 | 來回伺服器兩次,故較受網路連線品質影響。 | 僅來回伺服器僅一次,於伺服器內進行轉址的動作。 | 同Transfer() |
那麼,Server.Transfer()及 Server.Execute() 的差異為何呢?
Server.Execute()和Server.Transfer功能很相像。但主要的差別在,Execute在轉到新頁面執行完成後,會回到原頁面,插入新頁面輸出結果並【繼續】執行原頁面的後續程式碼。而Transfer在轉到新頁面並執行完成新頁面的輸出後,就並【不會繼續】執行原頁面的後續程式碼。
==================================================================
貼心小補充,連接伺服器的次數:
Response.Redirect()
這個跳轉頁面的方法跳轉的速度不快,因為它要走2個來回,但他可以跳轉到任何頁面,沒有站點頁面限制(即可以由雅虎跳到新浪),它需要重新驗證登入保護,因為已視為一個全新的網站連結。
Redirect跳轉機制:首先是傳送一個http請求到客戶端,通知需要跳轉到新頁面,然後客戶端在傳送跳轉請求到伺服器端。需要注意的是跳轉後內部空間儲存的所有資料資訊將會丟失,所以需要用到session。
Server.Transfer()
速度相對較快,因為它只需走1個來回,但他必須是跳轉在同一個站點下的頁面,因為它是server的一個方法。另外,它無須重新驗證登入保護,因為只是從同一個網站下的一個頁面移動至另一個頁面。另外,若希望藉由隱藏網址來達到保護網頁的保密功能,實務上多是使用HttpContext.RewritePath()來做 URL Rewriting (也就是保持網頁的 URL 不變)。
延伸閱讀:
https://www.developerfusion.com/article/4643/implementing-http-handlers-in-aspnet/4/
https://stackoverflow.com/questions/336813/server-transfer-vs-context-rewritepath
Sever.Execute()
這個方法主要是用在頁面設計上面,而且他必須是跳轉同一站點下的頁面。這個方法是需要將一個頁面的輸出結果插入到另一個aspx頁面的時候使用,大部分是在表格中,將某一個頁面類似於巢狀的方式存在於另一頁面。
參考資料:
https://codertw.com/%E5%89%8D%E7%AB%AF%E9%96%8B%E7%99%BC/199321/
https://dotblogs.com.tw/jimmyyu/archive/2009/11/10/11503.aspx (大推薦)
==================================================================
二、網頁跳轉的個別示範
為了瞭解網頁跳轉的實際作用及執行順序,我們須先完成一些預備動作,方便查看。
在detail.aspx.cs程式碼後置檔案中,顯示字串,this message is in detail.aspx
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace ShareTwo
{
public partial class detail : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Response.Write("detail.aspx.cs的內容");
}
}
}
在detail.aspx設計頁面中,顯示字串,detail.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="detail.aspx.cs" Inherits="ShareTwo.detail" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<span>detail.aspx的內容</span>
</div>
</form>
</body>
</html>
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="default.aspx.cs" Inherits="ShareTwo._default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<span>default.aspx的內容</span>
</div>
</form>
</body>
</html>
好了,我們的預備動作告一段落,接下來進行的測試都放在原頁面的後置程式碼檔案中(default.aspx.cs)
此方法將直接轉至新網址(不受限於同一站點內),故上方原頁面的輸出內容並不會出現在跳轉後的頁面。
Response.Write("Response.Redirect方法:");
Response.Redirect("detail.aspx");
Response.Write("測試 Redirect");
頁面顯示:
值得注意的,如下
Transfer在轉到新頁面並執行完成新頁面的輸出後,就並【不會繼續】執行原頁面的後續程式碼,故下方的原頁面輸出內容(測試 Transfer)並不會出現。
Response.Write("Transfer方法:");
Server.Transfer("detail.aspx");
Response.Write("測試 Transfer");
頁面顯示:
值得注意的,如下
Execute在轉到新頁面執行完成後,會回到原頁面,插入新頁面輸出結果並【繼續】執行原頁面的後續程式碼。
==================================================================
**貼心小補充,感謝朱大補充
不過,Server.Execute() 其實也不是設計用來跳轉的,它主要的目的是在 ASP.NET 內執行別的網頁 (例如執行交易的網頁) 再將結果寫入到 Response 內,例如要在一個要求內同時對不同的 aspx 做叫用時,只需要發一個要求就可以在程式內叫用 Server.Execute() 對其他要操作的頁面做呼叫,而回傳時只會看到執行結果,因此有可能是有結果 (有輸出) 或沒有結果 (沒有輸出) 的情況,不過在近幾年來的演進,已經幾乎不使用 Server.Execute() 了,而是改用 HTTP client 去叫用,這樣的好處是可以得到執行結果做進一步處理 (即便被叫用的aspx是在同一個專案的也是),但 Server.Execute() 是直接把結果寫入到 Response,程式連處理的機會都沒有。只能說 Server.Execute() 比較像是要相容 ASP 的舊思維才保留的吧。
==================================================================
Response.Write(".Execute方法:");//在不變更URL下,將頁面轉至同伺服器底下的其他網頁,執行完畢後將回到原本.aspx "繼續執行"
Server.Execute("detail.aspx");// detail.aspx 這頁面內容為 this message is in detail.aspx
Response.Write("測試 Execute");
頁面顯示:
值得注意的,如下
此篇內容整理自多篇網路文章、PPT及自己的理解,但筆者也仍處在初階的學習過程,對程式概念的理解及判斷都尚不足,若有錯誤的地方,也煩請各位大大提點,先謝謝大家惹!!
明日(9/23)預定探討課題:
網頁暫存(Application、Session、Cookie、Cache)
這一段用 "編譯" 怪怪的,應該是 "執行" 才對,編譯在 ASP.NET 只會在第一次執行時才會有所謂的即時編譯 (JIT, 將 MSIL code 編譯成 native code),第二次以後就不會再編譯,直到 IIS 在閒置時間到時釋放所有 DLL 後又再次被喚起,才會又再做一次 JIT 編譯。
這有點誤解,Response.Redirect 是傳給用戶端 HTTP 302 (REDIRECT) 指令,由瀏覽器做跳轉,另外,PostBack 和要求 (Request) 雖然很像但行為有一點差異,PostBack也是一種要求,但PostBack會帶網頁上的ViewState回Server,Server會判斷要求中有沒有這項資訊,有的話才會把 IsPostBack設為true,但單純的要求不算是PostBack (包含第一次的aspx要求)。
可參考:
https://www.developerfusion.com/article/4643/implementing-http-handlers-in-aspnet/4/
https://stackoverflow.com/questions/336813/server-transfer-vs-context-rewritepath
謝謝朱大,讓我開了很多觀念(編譯、postback...等),還補充了HttpContext.RewritePath()的用法及分享Server.Execute()設計概念與我們會在實務上的作法